/**
 * 监控处理器
 * 负责具体的监控逻辑实现
 */

import { useMonitor } from './index';

/**
 * JavaScript错误监控处理器
 */
export class JavaScriptErrorHandler {
  private monitor = useMonitor();

  /**
   * 初始化JavaScript错误监控
   */
  init() {
    if (!process.client) return;

    // 监听全局JavaScript错误和资源加载错误
    window.addEventListener('error', event => {
      const message = event.message || event.error?.message || '未知错误';
      const source = event.filename;
      const line = event.lineno;
      const column = event.colno;
      const stack = event.error?.stack;

      this.monitor.reportJavaScriptError(message, source, line, column, stack);
    });

    // 监听未捕获的Promise错误
    window.addEventListener('unhandledrejection', event => {
      const reason = event.reason;
      const message =
        reason?.message || reason?.toString() || '未知Promise错误';
      const stack = reason?.stack;

      this.monitor.reportJavaScriptError(
        message,
        undefined,
        undefined,
        undefined,
        stack
      );
    });

    console.log('🔍 [JavaScript错误监控] 初始化完成，开始监听页面错误...');
  }
}

/**
 * 网络错误监控处理器
 */
export class NetworkErrorHandler {
  private monitor = useMonitor();

  /**
   * 初始化网络错误监控
   */
  init() {
    if (!process.client) return;

    this.initFetchMonitor();
    this.initXHRMonitor();

    console.log('🌐 [网络错误监控] 初始化完成，开始监听网络请求错误...');
  }

  /**
   * 监控 fetch 请求
   */
  private initFetchMonitor() {
    const originalFetch = window.fetch;
    window.fetch = async function (
      input: RequestInfo | URL,
      init?: RequestInit
    ): Promise<Response> {
      const startTime = Date.now();
      const url = typeof input === 'string' ? input : input.toString();
      const method = init?.method || 'GET';

      try {
        const response = await originalFetch(input, init);
        const duration = Date.now() - startTime;

        // 检查响应状态
        if (!response.ok) {
          const message = `HTTP ${response.status} ${response.statusText}`;
          useMonitor().reportNetworkError(
            url,
            message,
            response.status,
            method
          );
        }

        return response;
      } catch (error: any) {
        const message = error.message || error.toString();
        useMonitor().reportNetworkError(url, message, undefined, method);
        throw error; // 重新抛出错误，保持原有的错误处理流程
      }
    };
  }

  /**
   * 监控 XMLHttpRequest 请求
   */
  private initXHRMonitor() {
    const originalXHROpen = XMLHttpRequest.prototype.open;
    const originalXHRSend = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function (
      method: string,
      url: string | URL,
      async: boolean = true,
      user?: string | null,
      password?: string | null
    ) {
      // 保存请求信息
      (this as any)._requestInfo = {
        method: method.toUpperCase(),
        url: url.toString(),
        startTime: 0,
      };

      return originalXHROpen.call(this, method, url, async, user, password);
    };

    XMLHttpRequest.prototype.send = function (
      body?: XMLHttpRequestBodyInit | null
    ) {
      const requestInfo = (this as any)._requestInfo;
      if (requestInfo) {
        requestInfo.startTime = Date.now();
        requestInfo.requestData = body;
      }

      // 监听请求完成
      this.addEventListener('loadend', function () {
        if (requestInfo) {
          // 检查是否有错误
          if (this.status === 0 || this.status >= 400) {
            const message =
              this.status === 0
                ? '网络连接失败或请求被阻止'
                : `HTTP ${this.status} ${this.statusText}`;

            useMonitor().reportNetworkError(
              requestInfo.url,
              message,
              this.status,
              requestInfo.method
            );
          }
        }
      });

      // 监听网络错误
      this.addEventListener('error', function () {
        if (requestInfo) {
          useMonitor().reportNetworkError(
            requestInfo.url,
            '网络请求失败',
            undefined,
            requestInfo.method
          );
        }
      });

      // 监听超时错误
      this.addEventListener('timeout', function () {
        if (requestInfo) {
          useMonitor().reportNetworkError(
            requestInfo.url,
            '请求超时',
            undefined,
            requestInfo.method
          );
        }
      });

      return originalXHRSend.call(this, body);
    };
  }
}

/**
 * 性能监控处理器
 */
export class PerformanceHandler {
  private monitor = useMonitor();

  /**
   * 初始化性能监控
   */
  init() {
    if (!process.client) return;

    this.initPerformanceReporting();
    console.log('🚀 [性能监控] 初始化完成，开始监听性能数据...');
  }

  /**
   * 初始化性能数据上报
   */
  private initPerformanceReporting() {
    // 页面完全加载后再上报指标
    if (document.readyState === 'complete') {
      setTimeout(() => {
        this.monitor.reportPerformance();
      }, 2000);
    } else {
      window.addEventListener('load', () => {
        setTimeout(() => {
          this.monitor.reportPerformance();
        }, 2000);
      });
    }

    // 在页面卸载时清理和最终上报
    window.addEventListener('beforeunload', () => {
      this.monitor.reportPerformance();
      this.monitor.disconnect();
    });

    // 页面可见性变化时也上报一次
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        this.monitor.reportPerformance();
      }
    });
  }
}

/**
 * Vue错误监控处理器
 */
export class VueErrorHandler {
  private monitor = useMonitor();

  /**
   * 初始化Vue错误监控
   */
  init(nuxtApp: any) {
    if (!process.client) return;

    this.initVueErrorHandler(nuxtApp);
    this.initVueWarningHandler(nuxtApp);
    this.initVueHookHandler(nuxtApp);

    console.log('⚡ [Vue错误处理] 初始化完成，开始监听Vue组件错误...');
  }

  /**
   * 从组件实例中提取有用信息
   */
  private extractComponentInfo(instance: any) {
    if (!instance) return {};

    return {
      componentName:
        instance.$options?.name ||
        instance.$options?._componentTag ||
        '匿名组件',
      route: instance.$route?.path || window.location.pathname,
      props: instance.$props,
      data: instance.$data,
    };
  }

  /**
   * 设置Vue全局错误处理器
   */
  private initVueErrorHandler(nuxtApp: any) {
    nuxtApp.vueApp.config.errorHandler = (
      err: unknown,
      instance: any,
      info: string
    ) => {
      const error = err as Error;
      const componentInfo = this.extractComponentInfo(instance);

      const message = error?.message || error?.toString() || '未知Vue错误';
      const componentName = componentInfo.componentName;
      const stack = error?.stack;

      this.monitor.reportVueError(message, componentName, stack);
    };
  }

  /**
   * 设置Vue警告处理器（开发环境）
   */
  private initVueWarningHandler(nuxtApp: any) {
    if (process.env.NODE_ENV === 'development') {
      nuxtApp.vueApp.config.warnHandler = (
        msg: string,
        instance: any,
        trace: string
      ) => {
        const componentInfo = this.extractComponentInfo(instance);

        // 警告级别的错误只在控制台显示，不上报
        console.group(`⚠️ [Vue组件警告] ${msg}`);
        console.log('🧩 组件名称:', componentInfo.componentName);
        if (componentInfo.route)
          console.log('🛣️ 当前路由:', componentInfo.route);
        if (trace) console.log('🔗 组件调用栈:', trace);
        console.log('⏰ 发生时间:', new Date().toLocaleString());
        console.groupEnd();
      };
    }
  }

  /**
   * 监听Vue渲染错误（针对异步组件）
   */
  private initVueHookHandler(nuxtApp: any) {
    nuxtApp.hook('vue:error', (error: any, instance: any, info: string) => {
      const componentInfo = this.extractComponentInfo(instance);

      const message = error?.message || error?.toString() || '异步组件错误';
      const componentName = componentInfo.componentName;
      const stack = error?.stack;

      this.monitor.reportVueError(message, componentName, stack);
    });
  }
}
